/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package votingkeypair;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 *
 * @author Maciek
 */
public class ShamirsSecret {
    
    ArrayList<String> secrets;
    int n,k;
    String baseName;
    private String realSecret;
    
    public String getSecret(){
        if(realSecret == null){
            return "No secret Man";
        }
        else return (String) realSecret.subSequence(1, realSecret.length()-1);
        
    }
    public String[] getKSecrets(int beg, int k){
        String[] s = new String[k];
        for(int i = beg ; i < k+beg; ++i)
            s[i-beg] = secrets.get(i);
        return s;
    }
    
    public int fileShamirSecret(String baseName, String secret, int k, int n) throws IOException, InterruptedException{
        this.k = k;
        this.n = n;
        this.baseName = baseName;
        
        int result = splitShamirSecret(secret,k,n);
        System.out.println("result = " + result);
        if(result!=0) return result;
        for(int i = 0 ; i < n ; ++i){
            writeFile(secrets.get(i), getName(baseName,i+1));
        }
        return result;
    }
    
    private String getName(String baseName, int i){
        return baseName + i + ".txt";
    }
    
    private void writeFile(String text, String fileName) throws IOException{

    
        BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
        out.write(text);
        out.close();
    

    }
    
    private String builldsplitShamirSecretCommand(String secret, int k, int n){
        StringBuilder sb = new StringBuilder();
        sb.append("cmd.exe /c java -jar secretshare-v1.1.jar split -k ").append(k);
        sb.append(" -n ").append(n);
        sb.append(" -sS ").append(secret);
        return sb.toString();
    }
    
    public int splitShamirSecret(String secret, int k, int n) throws IOException, InterruptedException{
        String command = this.builldsplitShamirSecretCommand(secret, k, n);
        System.out.println("Chce wykonać : " + command);
        Process proc = Runtime.getRuntime().exec(command);
        secrets =  getInput(proc); // wypisuje wszystko co otrzymam z odpowiedniego miejsca
        return proc.waitFor();
    }
    
    
    private ArrayList<String> parseOutput(BufferedReader reader) throws IOException{
        ArrayList<String> parts = new ArrayList<String>();
        String line; String share = "Share";
        while ((line = reader.readLine())!= null){
            System.out.println ("[Stdout] " + line);
            if(line.startsWith(share)){
                String t[] = line.split("=");
                parts.add(t[1].trim());
            }
            
        }
        return parts;
    }
    private ArrayList<String> getInput(Process proc) throws IOException{ // tu pożnaby zapisywać do jakiś plików
         InputStream stdout = proc.getInputStream();
        String line;
        InputStream stderr = proc.getErrorStream();
          BufferedReader brCleanUp =
        new BufferedReader (new InputStreamReader (stdout));
        ArrayList<String> res = parseOutput(brCleanUp);
        
          brCleanUp.close();

          // clean up if any output in stderr
          brCleanUp =
            new BufferedReader (new InputStreamReader (stderr));
          while ((line = brCleanUp.readLine ()) != null) {
            System.out.println ("[Stderr] " + line);
          }
          brCleanUp.close();
          
         return res;
    } 
    
    private String recoverSecret(BufferedReader reader) throws IOException{
        String result = null;
        String line; String secretString = "secret.string";
        while ((line = reader.readLine())!= null){
            System.out.println ("[Stdout] " + line);
            if(line.startsWith(secretString)){
               String [] t = line.split("=");
               result = t[1].trim();
            }
            
        }
        return result;
    }
    
    private String getInputSecret(Process proc) throws IOException{ // tu pożnaby zapisywać do jakiś plików
         InputStream stdout = proc.getInputStream();
        String line;
        InputStream stderr = proc.getErrorStream();
          BufferedReader brCleanUp =
        new BufferedReader (new InputStreamReader (stdout));
       
        String result = recoverSecret(brCleanUp);
          brCleanUp.close();

          // clean up if any output in stderr
          brCleanUp =
            new BufferedReader (new InputStreamReader (stderr));
          while ((line = brCleanUp.readLine ()) != null) {
            System.out.println ("[Stderr] " + line);
          }
          brCleanUp.close();
          
         return result;
    } 
    
    void showSecrets(){
        for (String s : secrets){
            System.out.println(s);
        }
    }
    
    private String buildCombineShamirSecretCommand(int k, String[] secrets, int[] ids){
        StringBuilder sb = new StringBuilder();
        sb.append("cmd.exe /c java -jar secretshare-v1.1.jar combine -k ").append(k);
        for( int i = 0 ; i < ids.length ; ++i){
            sb.append(" -s").append(ids[i]).append(" ").append(secrets[i]);
        }
        return sb.toString();
    }
    
     public int combineShamirSecret(int k, String[] secrets , int[] ids) throws IOException, InterruptedException{
        this.realSecret = null;
        String command = this.buildCombineShamirSecretCommand(k,secrets, ids);
        System.out.println("Chce wykonać : " + command);
        Process proc = Runtime.getRuntime().exec(command);
        realSecret = getInputSecret(proc); // wypisuje wszystko co otrzymam z odpowiedniego miejsca
        return proc.waitFor();
    }
     
    public int fileCombineShamirSecret(String base , int k , int ids[]) throws IOException, InterruptedException{
        String[] s = getSecrets(base, k, ids);
        
        return combineShamirSecret(k, s, ids);
    }
    String[] getSecrets(String base, int k , int[] ids) throws IOException{
        String[] s = new String[k];
        for(int i = 0 ; i < k ; ++i){
            s[i] = readFromFile(getName(base,ids[i]));
        }
        return s;
               
    }
    
    String readFromFile(String fileName) throws IOException{
        BufferedReader in = new BufferedReader(new FileReader(fileName));
        String str;
        StringBuilder sb = new StringBuilder();
        while ((str = in.readLine()) != null) {
            sb.append(str);
        }
        return sb.toString();
    }
}
